#include "Application.h"

extern CApplication *g_pApp;
static LPCWSTR      lpClassName = L"Rat Engine 2.000";
static HINSTANCE	hInstance;

LRESULT CALLBACK WndProc(	HWND	hWnd,			
							UINT	uMsg,			
							WPARAM	wParam,			
							LPARAM	lParam)			
{
    if (g_pApp == NULL)
        return DefWindowProc(hWnd,uMsg,wParam,lParam);

    if (!g_pApp->OnInput(uMsg, wParam, lParam))
	    return DefWindowProc(hWnd,uMsg,wParam,lParam);
    else
        return 0;
}

CApplication::CApplication( int a_iWidth, int a_iHeight )
: m_hWnd(NULL), m_hDC(NULL), m_bActive(true)
{
    RECT WndRect;
    WndRect.left    = 0;
    WndRect.bottom  = a_iHeight;
    WndRect.right   = a_iWidth;
    WndRect.top     = 0;
    InitWindow(WndRect);
    ShowWindow();
	ZeroMemory( m_bKeys, sizeof(m_bKeys) );
};

CApplication::~CApplication() 
{
    delete m_pTestObj;
    UnregisterClass(lpClassName, hInstance);	
	hInstance = NULL;
};

void CApplication::ShowWindow()
{
    ::ShowWindow(m_hWnd, SW_SHOW);	
	SetForegroundWindow(m_hWnd);	
	SetFocus(m_hWnd);
}

void CApplication::InitWindow(RECT a_WindowRect)
{
    WNDCLASS	wc;						
	DWORD		dwExStyle;				
	DWORD		dwStyle;	

    hInstance			= GetModuleHandle(NULL);				// Grab An Instance For Our Window
	wc.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;	// Redraw On Size, And Own DC For Window.
	wc.lpfnWndProc		= (WNDPROC) WndProc;					// WndProc Handles Messages
	wc.cbClsExtra		= 0;									// No Extra Window Data
	wc.cbWndExtra		= 0;									// No Extra Window Data
	wc.hInstance		= hInstance;							// Set The Instance
	wc.hIcon			= LoadIcon(NULL, IDI_WINLOGO);			// Load The Default Icon
	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);			// Load The Arrow Pointer
	wc.hbrBackground	= NULL;									// No Background Required For GL
	wc.lpszMenuName		= NULL;									// We Don't Want A Menu
	wc.lpszClassName	= lpClassName;								// Set The Class Name

	RegisterClass(&wc);
    dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;			
	dwStyle = WS_OVERLAPPEDWINDOW;							

	AdjustWindowRectEx(&a_WindowRect, dwStyle, FALSE, dwExStyle);		// Adjust Window To True Requested Size

	m_hWnd = CreateWindowEx   (	dwExStyle,							
								lpClassName,							
								NULL,								// Window Title
								dwStyle |							// Defined Window Style
								WS_CLIPSIBLINGS |					// Required Window Style
								WS_CLIPCHILDREN,					// Required Window Style
								0, 0,								// Window Position
								a_WindowRect.right - a_WindowRect.left,	// Calculate Window Width
								a_WindowRect.bottom - a_WindowRect.top,	// Calculate Window Height
								NULL,								// No Parent Window
								NULL,								// No Menu
								hInstance,							// Instance
								NULL);								// Dont Pass Anything To WM_CREATE
}

void CApplication::Exec()
{
    MSG     msg;
    BOOL    done = 0;

    InitScene();

    while ( !done )                                 
    {
        if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))   
        {
            if (msg.message==WM_QUIT)               
            {
                done = TRUE;                        
            }
            else                                    
            {
                TranslateMessage(&msg);             
                DispatchMessage(&msg);              
            }
        }
        else                                        
        {
            //OnInput();
            UpdateScene();
            RenderScene();
        }
    }
}

void CApplication::ResizeScene(int a_iWidth, int a_iHeight)
{
    m_iWidth  = a_iWidth;
    m_iHeight = a_iHeight;
}

void CApplication::InitScene()
{
    m_pTestObj = new CTestObj;
}

void CApplication::UpdateScene()
{

}

void CApplication::RenderScene()
{
    m_pTestObj->Render();
}

bool CApplication::OnInput( UINT a_Msg, int a_WParam, long a_LParam )
{
    /* Cursor pos handler */
    POINT CurPos;
    GetCursorPos(&CurPos);
    //if (g_pApp)
    {
        m_iCurPosdX = CurPos.x - m_iCursorPosX;
        m_iCurPosdY = CurPos.y - m_iCursorPosY;
        m_iCursorPosX = CurPos.x;
        m_iCursorPosY = CurPos.y;
    }
    switch (a_Msg)									
    {
        case WM_ACTIVATE:							
        {
            SetActive(LOWORD(a_WParam) != WA_INACTIVE);

            return true;								
        }
        case WM_SYSCOMMAND:							
        {
            switch (a_WParam)							
            {
            case SC_SCREENSAVE:					
            case SC_MONITORPOWER:				
                return true;							
            }
            break;									
        }

        case WM_CLOSE:								
        {
            PostQuitMessage(0);						
            return true;								
        }

        case WM_KEYDOWN:							
        {
            m_bKeys[a_WParam] = true;					
            return true;							
        }

        case WM_KEYUP:							
        {
            m_bKeys[a_WParam] = false;					
            return true;							
        }

        case WM_SIZE:							
        {
            ResizeScene(LOWORD(a_LParam), HIWORD(a_LParam));
            return true;								
        }
        default:
            return false;
    }
    return false;    
}

void CApplication::SetActive(bool a_bActive)
{
    m_bActive = a_bActive;
}